package org.shopen.ai.puremvc.model.domain.cities
{
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.mxml.HTTPService;
	
	import org.puremvc.as3.patterns.proxy.Proxy;
	import org.shopen.ai.puremvc.ApplicationConstants;
	import org.shopen.ai.puremvc.ApplicationParameters;
	import org.shopen.ai.puremvc.model.utils.CompleteDelegate;
	import org.un.cava.birdeye.ravis.graphLayout.data.Graph;
	import org.un.cava.birdeye.ravis.graphLayout.data.IGraph;

	public class CountryProxy extends Proxy
	{
		public static const NAME : String 							= "CountryProxy";
		public static const COUNTRY_LOADED : String 				= NAME + "." + "COUNTRY_LOADED";
		public static const COUNTRY_LOAD_FAILED : String 			= NAME + "." + "COUNTRY_LOAD_FAILED";
		public static const COUNTRY_MAPDATA_LOADED : String 		= NAME + "." + "COUNTRY_MAPDATA_LOADED";
		public static const COUNTRY_MAPDATA_LOAD_FAILED : String 	= NAME + "." + "COUNTRY_MAPDATA_LOAD_FAILED";
		public static const COUNTRY_GRAPH_LOADED : String 			= NAME + "." + "COUNTRY_GRAPH_LOADED";
		public static const COUNTRY_GRAPH_LOAD_FAILED : String 		= NAME + "." + "COUNTRY_GRAPH_LOAD_FAILED";
		
		private var _service : HTTPService;
		protected function get service() : HTTPService
		{
			return _service;
		}
		protected function set service(value : HTTPService) : void
		{
			_service = value;
		}
		
		protected var completeDelegate : CompleteDelegate = null;
				
		public function get country() : Country
		{
			var result : Country = data as Country;
			return result;
		}
		
		public function get isDataLoaded() : Boolean
		{
			var result : Boolean = getData() != null;
			return result;
		}
		
		protected var _countryGraph : IGraph = null;
		public function get countryGraph() : IGraph
		{
			return _countryGraph;
		}
		
		public function CountryProxy(data:Object=null)
		{
			super(CountryProxy.NAME, data);
		}
		
		override public function getProxyName():String
		{
			return CountryProxy.NAME;
		}
		
		override public function onRegister():void
		{
			setService();
		}
			
		private function setService() : void
		{
			service = new HTTPService();
			service.url = ApplicationParameters.COUNTRY_PATH;
			service.resultFormat = "e4x";
			service.addEventListener(ResultEvent.RESULT, serviceResultListener);
			service.addEventListener(FaultEvent.FAULT, serviceFaultListener);
		}
		
		private function serviceResultListener(event : ResultEvent) : void
		{
			var dataXML : XML = event.result as XML;
			var country : Country = new Country(dataXML);
			setData(country);
			sendResult();
			sendCompleteEvent();
		}
		
		private function serviceFaultListener(event : FaultEvent) : void
		{
			sendNotification(CountryProxy.COUNTRY_LOAD_FAILED, event.message.toString());
		}
		
		private function sendResult() : void
		{
			sendNotification(CountryProxy.COUNTRY_LOADED, country);
		}
		
		private function sendCompleteEvent() : void
		{
			if (completeDelegate != null)
			{
				completeDelegate.dispatchComplete();
			}
		}
		
		public function loadData(completeDelegate : CompleteDelegate = null) : void
		{
			this.completeDelegate = completeDelegate;
			if (isDataLoaded)
			{
				sendResult();
				sendCompleteEvent();
			}
			else
			{
				service.send();
			}
		}
		
		public function loadMapData(id : String, value: Country = null) : void
		{
			try
			{
				var resBody : XML = null;
				if (value != null)
				{
					resBody = value.toRavisXml();
				}
				else
				{
					resBody = this.country.toRavisXml();
				}
				sendNotification(CountryProxy.COUNTRY_MAPDATA_LOADED, resBody, id);
			}
			catch (e : Error)
			{
				sendNotification(COUNTRY_MAPDATA_LOAD_FAILED, null, id);
			}
		}
		
		public function loadCountryGraph(id : String = null) : void
		{
			try
			{
				if (countryGraph == null)
				{
					_countryGraph = generateGraph(this.country, this.country.title);
				}
				sendNotification(COUNTRY_GRAPH_LOADED, countryGraph, id);
			}
			catch (e : Error)
			{
				sendNotification(COUNTRY_GRAPH_LOAD_FAILED, null, id);
			}
		}
		
		public function generateGraph(country : Country, graphId : String) : IGraph
		{
			var xmlData : XML = country.toRavisXml();
			var result : IGraph = new Graph(graphId, false, xmlData);
			return result;
		}
		
		public function getCityById(id : int) : City
		{
			var result : City = null;
			try
			{
				for each (var city : City in country.cities)
				{
					if (city.id == id)
					{
						result = city;
					}
				}
			}
			catch (e : Error)
			{
				sendNotification(ApplicationConstants.GENERAL_ERROR, "Error while getting city by id");
			}
			finally
			{
				return result;
			}
		} 
	}
}